home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / fax / src / faxd / GettySysV.c++ < prev    next >
C/C++ Source or Header  |  1994-08-01  |  6KB  |  224 lines

  1. /*    $Header: /usr/people/sam/fax/faxd/RCS/GettySysV.c++,v 1.29 1994/02/28 14:15:25 sam Rel $ */
  2. /*
  3.  * Copyright (c) 1990, 1991, 1992, 1993, 1994 Sam Leffler
  4.  * Copyright (c) 1991, 1992, 1993, 1994 Silicon Graphics, Inc.
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software and 
  7.  * its documentation for any purpose is hereby granted without fee, provided
  8.  * that (i) the above copyright notices and this permission notice appear in
  9.  * all copies of the software and related documentation, and (ii) the names of
  10.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  11.  * publicity relating to the software without the specific, prior written
  12.  * permission of Sam Leffler and Silicon Graphics.
  13.  * 
  14.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  15.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  16.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  17.  * 
  18.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  19.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  20.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  21.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  22.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  23.  * OF THIS SOFTWARE.
  24.  */
  25. #include <limits.h>
  26. #include <stddef.h>
  27. #include <termios.h>
  28. #include <osfcn.h>
  29. #include <paths.h>
  30. #include <sys/wait.h>
  31. #include <sys/stat.h>
  32. #include <sys/ioctl.h>
  33. #include <utmp.h>
  34. #include <fcntl.h>
  35.  
  36. #include "GettySysV.h"
  37.  
  38. #ifndef _PATH_WTMP
  39. #define    _PATH_WTMP    WTMP_FILE
  40. #endif
  41.  
  42. /*
  43.  * FAX Server System V Getty Support.
  44.  */
  45.  
  46. SysVGetty::SysVGetty(const fxStr& l, const fxStr& s, u_int t) : Getty(l,s,t)
  47. {
  48. }
  49.  
  50. SysVGetty::~SysVGetty()
  51. {
  52. }
  53.  
  54. fxBool
  55. SysVGetty::isSysVGetty()
  56. {
  57.     return (access((char*) getty, X_OK) == 0);
  58. }
  59.  
  60. Getty*
  61. OSnewGetty(const fxStr& dev, const fxStr& speed)
  62. {
  63.     return (SysVGetty::isSysVGetty() ? new SysVGetty(dev, speed) : NULL);
  64. }
  65.  
  66. /*
  67.  * ``Open'' the device and setup the initial tty state
  68.  * so that the normal stdio routines can be used.
  69.  */
  70. void
  71. SysVGetty::setupSession(int modemFd)
  72. {
  73.     int fd;
  74.     /*
  75.      * Close everything down except the modem so
  76.      * that the remote side doesn't get hung up on.
  77.      */
  78.     for (fd = _POSIX_OPEN_MAX-1; fd >= 0; fd--)
  79.     if (fd != modemFd)
  80.         (void) close(fd);
  81.     fclose(stdin);
  82.     /*
  83.      * Now make the line be the controlling tty
  84.      * and create a new process group/session for
  85.      * the login process that follows.
  86.      */
  87.     fd = open("tty", 0);        // NB: assumes we're in /dev
  88.     if (fd >= 0) {
  89. #ifdef TIOCNOTTY
  90.     (void) ioctl(fd, TIOCNOTTY, 0);
  91. #else
  92.     (void) setpgrp();
  93. #endif
  94.     (void) close(fd);
  95.     }
  96.     (void) setsid();
  97.     fd = open(getLine(), O_RDWR|O_NONBLOCK);
  98.     if (fd != STDIN_FILENO)
  99.     fatal("Can not setup \"%s\" as stdin", getLine());
  100.     if (fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) &~ O_NONBLOCK))
  101.     fatal("Can not reset O_NONBLOCK: %m");
  102.     close(modemFd);            // done with this, pitch it
  103.  
  104.     /*
  105.      * Turn off CLOCAL so that SIGHUP is sent on modem disconnect.
  106.      */
  107.     struct termios term;
  108.     if (tcgetattr(fd, &term) == 0) {
  109.     term.c_cflag &= ~CLOCAL;
  110.     (void) tcsetattr(fd, TCSAFLUSH, &term);
  111.     }
  112. #ifdef TIOCSSOFTCAR
  113.     /* turn the Solaris 2 soft carrier "feature" off */
  114.     { int off = 0; (void) ioctl(fd, TIOCSSOFTCAR, &off); }
  115. #endif
  116.     /*
  117.      * Setup descriptors for stdout, and stderr.
  118.      * Establish the initial line termio settings and set
  119.      * protection on the device file.  Finally, update the
  120.      * utmp and wtmp files to reflect the login attempt
  121.      * (login will abort if the utmp entry is not present).
  122.      */
  123.     struct stat sb;
  124.     (void) stat(getLine(), &sb);
  125.     (void) chown(getLine(), 0, sb.st_gid);
  126.     (void) chmod(getLine(), 0622);
  127.     if (dup2(fd, STDOUT_FILENO) < 0)
  128.     fatal("Unable to dup stdin to stdout: %m");
  129.     if (dup2(fd, STDERR_FILENO) < 0)
  130.     fatal("Unable to dup stdin to stderr: %m");
  131.  
  132.     loginAccount();
  133. }
  134.  
  135. void
  136. SysVGetty::writeWtmp(utmp* ut)
  137. {
  138.     // append record of login to wtmp file
  139. #ifndef svr4
  140.     int fd = open(_PATH_WTMP, O_WRONLY|O_APPEND);
  141.     if (fd >= 0) {
  142.     write(fd, (char *)ut, sizeof (*ut));
  143.     close(fd);
  144.     }
  145. #else
  146.     updwtmpx(WTMPX_FILE, ut);
  147. #endif
  148. }
  149.  
  150. /*
  151.  * Record the login session.
  152.  */
  153. void
  154. SysVGetty::loginAccount()
  155. {
  156.     static utmp ut;            // zero unset fields
  157.     ut.ut_pid = getpid();
  158.     ut.ut_type = LOGIN_PROCESS;
  159. #ifndef __linux__
  160.     ut.ut_exit.e_exit = 0;
  161.     ut.ut_exit.e_termination = 0;
  162. #endif
  163.     ut.ut_time = time(0);
  164.     // mark utmp entry as a login
  165.     strncpy(ut.ut_user, "LOGIN", sizeof (ut.ut_user));
  166.     /*
  167.      * For SVR4 systems, use the trailing component of
  168.      * the pathname to avoid problems where truncation
  169.      * results in non-unique identifiers.
  170.      */
  171.     fxStr id(getLine());
  172.     if (id.length() > sizeof (ut.ut_id))
  173.     id.remove(0, id.length() - sizeof (ut.ut_id));
  174.     strncpy(ut.ut_id, (char*) id, sizeof (ut.ut_id));
  175.     strncpy(ut.ut_line, getLine(), sizeof (ut.ut_line));
  176.     setutent();
  177.     pututline(&ut);
  178.     endutent();
  179.     writeWtmp(&ut);
  180. }
  181.  
  182. /*
  183.  * Record the termination of login&co and
  184.  * reset the state of the tty device.  Note
  185.  * that this is called in the parent and
  186.  * that we're entered with effective uid set
  187.  * to the fax user and real uid of root.  Thus
  188.  * we have to play games with uids in order
  189.  * to write the utmp&wtmp entries, etc.
  190.  */
  191. void
  192. SysVGetty::hangup()
  193. {
  194.     // at this point we're root and we can reset state
  195.     struct utmp* ut;
  196.     setutent();
  197.     while ((ut = getutent()) != NULL) { 
  198.     if (strncmp(ut->ut_line, getLine(), sizeof (ut->ut_line)) != 0)
  199.         continue;
  200.     strncpy(ut->ut_user, "DEAD", sizeof (ut->ut_user));
  201.     ut->ut_type = DEAD_PROCESS;
  202. #ifndef __linux__
  203.     ut->ut_exit.e_exit = (exitStatus >> 8) & 0xff;        // XXX
  204.     ut->ut_exit.e_termination = exitStatus & 0xff;        // XXX
  205. #endif
  206.     ut->ut_time = time(0);
  207.     pututline(ut);
  208.     writeWtmp(ut);
  209.     break;
  210.     }
  211.     endutent();
  212.     Getty::hangup();
  213. }
  214.  
  215. fxBool
  216. SysVGetty::wait(int& status, fxBool block)
  217. {
  218.     if (waitpid(getPID(), &exitStatus, block ? 0 : WNOHANG) == getPID()) {
  219.     status = exitStatus;
  220.     return (TRUE);
  221.     } else
  222.     return (FALSE);
  223. }
  224.